import React, { useState, useEffect, useRef } from 'react';
import io from 'socket.io-client';
import './VoiceRoom.css';

const VoiceRoom = () => {
  const [isMuted, setIsMuted] = useState(false);
  const [isConnected, setIsConnected] = useState(false);
  const [roomId, setRoomId] = useState('');
  const [participants, setParticipants] = useState([]);
  const [showCopied, setShowCopied] = useState(false);
  const [error, setError] = useState('');
  
  const localStreamRef = useRef(null);
  const socketRef = useRef(null);
  const peerConnections = useRef({});
  const audioElements = useRef({});

  useEffect(() => {
    return () => {
      cleanup();
    };
  }, []);

  const initializeLocalStream = async () => {
    try {
      // 检查是否在安全上下文中
      if (window.location.protocol !== 'https:' && window.location.hostname !== 'localhost' && window.location.hostname !== '127.0.0.1') {
        setError('当前页面不安全，请使用以下方式访问：\n1. 使用 https:// 协议\n2. 使用 localhost 或 127.0.0.1\n3. 在浏览器设置中允许不安全来源访问麦克风');
        return false;
      }

      // 优化音频设置，减少延迟
      const stream = await navigator.mediaDevices.getUserMedia({
        audio: {
          echoCancellation: true,
          noiseSuppression: true,
          autoGainControl: true,
          sampleRate: 48000,
          channelCount: 1,
          latency: 0.01, // 低延迟设置
          googEchoCancellation: true,
          googAutoGainControl: true,
          googNoiseSuppression: true
        }
      });
      localStreamRef.current = stream;
      console.log('Local stream initialized:', stream.getAudioTracks()[0].label);
      setError(''); // 清除之前的错误信息
      return true;
    } catch (error) {
      console.error('Error accessing microphone:', error);
      let errorMessage = '无法访问麦克风';
      if (error.name === 'NotAllowedError') {
        errorMessage = '请允许浏览器访问麦克风，并刷新页面重试';
      } else if (error.name === 'NotFoundError') {
        errorMessage = '未检测到麦克风设备，请检查设备连接';
      } else if (error.name === 'NotReadableError') {
        errorMessage = '麦克风可能被其他应用程序占用，请关闭其他使用麦克风的程序后重试';
      } else if (error.name === 'SecurityError') {
        errorMessage = '由于安全限制，请在以下环境使用：\n1. 使用 https:// 协议\n2. 使用 localhost 或 127.0.0.1\n3. 在浏览器设置中允许不安全来源访问麦克风';
      }
      setError(errorMessage);
      return false;
    }
  };

  const cleanup = () => {
    if (localStreamRef.current) {
      localStreamRef.current.getTracks().forEach(track => track.stop());
    }
    Object.values(peerConnections.current).forEach(pc => pc.close());
    Object.values(audioElements.current).forEach(audio => {
      audio.pause();
      audio.srcObject = null;
    });
    if (socketRef.current) {
      socketRef.current.disconnect();
    }
  };

  const createPeerConnection = (userId) => {
    // 优化ICE服务器配置，使用更多的STUN/TURN服务器
    const peerConnection = new RTCPeerConnection({
      iceServers: [
        { urls: 'stun:stun.l.google.com:19302' },
        { urls: 'stun:stun1.l.google.com:19302' },
        { urls: 'stun:stun2.l.google.com:19302' },
        { urls: 'stun:stun3.l.google.com:19302' },
        { urls: 'stun:stun4.l.google.com:19302' }
      ],
      iceTransportPolicy: 'all',
      iceCandidatePoolSize: 10, // 增加候选池大小
      bundlePolicy: 'max-bundle' // 优化媒体捆绑
    });

    // 添加本地流
    if (localStreamRef.current) {
      localStreamRef.current.getTracks().forEach(track => {
        console.log('Adding track to peer connection:', track.kind);
        peerConnection.addTrack(track, localStreamRef.current);
      });
    }

    // 处理远程流
    peerConnection.ontrack = (event) => {
      console.log('Received remote track:', event.track.kind);
      const audioElement = new Audio();
      audioElement.srcObject = event.streams[0];
      audioElement.autoplay = true;
      audioElement.volume = 1.0;
      audioElements.current[userId] = audioElement;
      
      // 确保音频开始播放
      audioElement.play().catch(error => {
        console.error('Error playing audio:', error);
      });
    };

    // 优化：批量发送ICE候选
    let candidateQueue = [];
    let candidateTimeout = null;
    
    // 处理ICE候选
    peerConnection.onicecandidate = (event) => {
      if (event.candidate) {
        candidateQueue.push(event.candidate);
        
        // 如果已经有定时器，不再创建新的
        if (!candidateTimeout) {
          // 50ms后批量发送候选
          candidateTimeout = setTimeout(() => {
            if (socketRef.current && candidateQueue.length > 0) {
              console.log(`Sending ${candidateQueue.length} ICE candidates`);
              socketRef.current.emit('ice-candidate', {
                candidate: candidateQueue.shift(), // 只发送第一个
                to: userId
              });
              
              // 如果队列中还有候选，继续发送
              if (candidateQueue.length > 0) {
                candidateTimeout = setTimeout(() => {
                  candidateTimeout = null;
                  peerConnection.onicecandidate({ candidate: candidateQueue.shift() });
                }, 20);
              } else {
                candidateTimeout = null;
              }
            }
          }, 50);
        }
      }
    };

    // 监听连接状态
    peerConnection.onconnectionstatechange = () => {
      const state = peerConnection.connectionState;
      console.log('Connection state:', state);
      
      if (state === 'failed' || state === 'disconnected' || state === 'closed') {
        // 连接失败时尝试重新协商
        console.log('Connection failed, attempting to reconnect...');
        if (socketRef.current && peerConnection.iceConnectionState !== 'closed') {
          // 尝试重新创建offer
          peerConnection.createOffer({ iceRestart: true })
            .then(offer => {
              return peerConnection.setLocalDescription(offer);
            })
            .then(() => {
              socketRef.current.emit('offer', {
                offer: peerConnection.localDescription,
                to: userId
              });
            })
            .catch(err => console.error('Error restarting ICE:', err));
        }
      }
    };

    // 添加ICE批量处理
    socketRef.current.on('ice-candidates-batch', async ({ candidates, from }) => {
      if (from === userId && peerConnection) {
        console.log(`Received batch of ${candidates.length} ICE candidates from:`, from);
        
        // 按顺序添加候选
        for (const candidate of candidates) {
          try {
            await peerConnection.addIceCandidate(new RTCIceCandidate(candidate));
          } catch (error) {
            console.error('Error adding ICE candidate:', error);
          }
        }
      }
    });

    return peerConnection;
  };

  const joinRoom = async () => {
    if (!roomId) return;
    setError('');

    // 显示连接中状态
    setError('正在连接...');

    const micAccessGranted = await initializeLocalStream();
    if (!micAccessGranted) {
      return;
    }

    try {
      // 连接信令服务器
      socketRef.current = io('http://192.168.43.51:3000', {
        reconnectionDelayMax: 10000,
        reconnectionAttempts: 10,
        transports: ['websocket', 'polling'],
        forceNew: true,
        timeout: 10000,
        query: {
          roomId: roomId,
          timestamp: Date.now() // 防止缓存
        }
      });
      
      // 连接超时处理
      const connectionTimeout = setTimeout(() => {
        if (socketRef.current && !socketRef.current.connected) {
          setError('连接服务器超时，请检查网络连接或刷新页面重试');
        }
      }, 10000);
      
      socketRef.current.on('connect', () => {
        clearTimeout(connectionTimeout);
        console.log('Connected to signaling server with ID:', socketRef.current.id);
        socketRef.current.emit('join-room', roomId);
        setIsConnected(true);
        setError(''); // 清除连接中状态
      });

      socketRef.current.on('user-joined', async (userId) => {
        console.log('User joined:', userId);
        // 防止重复创建连接
        if (peerConnections.current[userId]) {
          console.log('Connection already exists for:', userId);
          return;
        }
        
        const peerConnection = createPeerConnection(userId);
        peerConnections.current[userId] = peerConnection;

        try {
          const offer = await peerConnection.createOffer({
            offerToReceiveAudio: true,
            voiceActivityDetection: true
          });
          await peerConnection.setLocalDescription(offer);
          socketRef.current.emit('offer', {
            offer,
            to: userId
          });
        } catch (error) {
          console.error('Error creating offer:', error);
        }

        setParticipants(prev => {
          if (!prev.includes(userId)) {
            return [...prev, userId];
          }
          return prev;
        });
      });

      // 优化offer处理
      socketRef.current.on('offer', async ({ offer, from }) => {
        console.log('Received offer from:', from);
        
        // 如果已存在连接，先关闭
        if (peerConnections.current[from]) {
          peerConnections.current[from].close();
        }
        
        const peerConnection = createPeerConnection(from);
        peerConnections.current[from] = peerConnection;

        try {
          await peerConnection.setRemoteDescription(new RTCSessionDescription(offer));
          const answer = await peerConnection.createAnswer({
            voiceActivityDetection: true
          });
          await peerConnection.setLocalDescription(answer);
          socketRef.current.emit('answer', {
            answer,
            to: from
          });
          
          // 确保添加到参与者列表
          setParticipants(prev => {
            if (!prev.includes(from)) {
              return [...prev, from];
            }
            return prev;
          });
        } catch (error) {
          console.error('Error handling offer:', error);
        }
      });

      socketRef.current.on('answer', async ({ answer, from }) => {
        console.log('Received answer from:', from);
        const peerConnection = peerConnections.current[from];
        if (peerConnection) {
          try {
            await peerConnection.setRemoteDescription(new RTCSessionDescription(answer));
          } catch (error) {
            console.error('Error handling answer:', error);
          }
        }
      });

      socketRef.current.on('ice-candidate', async ({ candidate, from }) => {
        console.log('Received ICE candidate from:', from);
        const peerConnection = peerConnections.current[from];
        if (peerConnection) {
          try {
            await peerConnection.addIceCandidate(new RTCIceCandidate(candidate));
          } catch (error) {
            // 忽略已关闭连接的错误
            if (peerConnection.connectionState !== 'closed') {
              console.error('Error adding ICE candidate:', error);
            }
          }
        }
      });

      // 添加批量ICE候选处理
      socketRef.current.on('ice-candidates-batch', async ({ candidates, from }) => {
        console.log(`Received batch of ${candidates.length} ICE candidates from:`, from);
        const peerConnection = peerConnections.current[from];
        if (peerConnection) {
          for (const candidate of candidates) {
            try {
              await peerConnection.addIceCandidate(new RTCIceCandidate(candidate));
            } catch (error) {
              // 忽略已关闭连接的错误
              if (peerConnection.connectionState !== 'closed') {
                console.error('Error adding ICE candidate from batch:', error);
              }
            }
          }
        }
      });

      socketRef.current.on('user-left', (userId) => {
        console.log('User left:', userId);
        if (peerConnections.current[userId]) {
          peerConnections.current[userId].close();
          delete peerConnections.current[userId];
        }
        if (audioElements.current[userId]) {
          audioElements.current[userId].pause();
          audioElements.current[userId].srcObject = null;
          delete audioElements.current[userId];
        }
        setParticipants(prev => prev.filter(id => id !== userId));
      });

      socketRef.current.on('connect_error', (error) => {
        console.error('Connection error:', error);
        setError(`连接服务器失败: ${error.message}，请检查网络连接和服务器状态`);
      });

      // 添加重连逻辑
      socketRef.current.on('disconnect', (reason) => {
        console.log('Disconnected from server:', reason);
        if (reason === 'io server disconnect') {
          // 服务器主动断开，尝试重连
          socketRef.current.connect();
        }
        setError('与服务器的连接已断开，正在尝试重新连接...');
      });

      socketRef.current.on('reconnect', (attemptNumber) => {
        console.log('Reconnected to server after', attemptNumber, 'attempts');
        setError('');
        // 重新加入房间
        socketRef.current.emit('join-room', roomId);
      });

      socketRef.current.on('reconnect_error', (error) => {
        console.error('Reconnection error:', error);
        setError('重新连接失败，请刷新页面重试');
      });

      socketRef.current.on('reconnect_failed', () => {
        console.error('Failed to reconnect');
        setError('无法重新连接到服务器，请刷新页面重试');
      });

    } catch (error) {
      console.error('Error joining room:', error);
      setError('加入房间失败，请重试');
    }
  };

  const leaveRoom = () => {
    cleanup();
    setIsConnected(false);
    setParticipants([]);
    setError('');
  };

  const toggleMute = () => {
    if (localStreamRef.current) {
      const audioTrack = localStreamRef.current.getAudioTracks()[0];
      audioTrack.enabled = !audioTrack.enabled;
      setIsMuted(!isMuted);
    }
  };

  const copyRoomId = () => {
    navigator.clipboard.writeText(roomId).then(() => {
      setShowCopied(true);
      setTimeout(() => setShowCopied(false), 2000);
    });
  };

  return (
    <div className="voice-room">
      {error && <div className="error-message">{error}</div>}
      <div className="room-controls">
        {!isConnected ? (
          <>
            <input
              type="text"
              value={roomId}
              onChange={(e) => setRoomId(e.target.value)}
              placeholder="输入房间ID"
            />
            <button onClick={joinRoom}>加入房间</button>
          </>
        ) : (
          <>
            <div className="room-id-display">
              <span>房间号: {roomId}</span>
              <button onClick={copyRoomId} className="copy-button">
                {showCopied ? '已复制!' : '复制房间号'}
              </button>
            </div>
            <button onClick={leaveRoom}>离开房间</button>
          </>
        )}
        <button onClick={toggleMute}>
          {isMuted ? '取消静音' : '静音'}
        </button>
      </div>
      
      <div className="participants">
        <h3>房间成员 ({participants.length + 1})</h3>
        <div className="participants-list">
          <div className="participant">
            <span>我</span>
            <div className={`audio-indicator ${isMuted ? 'muted' : ''}`}></div>
          </div>
          {participants.map((participantId) => (
            <div key={participantId} className="participant">
              <span>用户 {participantId}</span>
              <div className="audio-indicator"></div>
            </div>
          ))}
        </div>
      </div>
    </div>
  );
};

export default VoiceRoom; 